package com.taosdata.example;

import com.taosdata.example.pool.*;
import lombok.extern.slf4j.Slf4j;

import javax.sql.DataSource;
import java.sql.*;

/**
 * @author PC
 */
@Slf4j
public class ConnectionPoolDemo {
    private static String host = "127.0.0.1";
    private static String dbName = "test_pool";
    /**
     * 可选值：c3p0、dbcp、druid、hikari
     */
    private static String poolType = "hikari";
    private static long totalSize = 1_000_000L;
    private static long tableSize = 1;
    private static long batchSize = 1;
    private static int poolSize = 50;
    private static int threadCount = 50;
    private static int sleep = 0;

    public static void main(String[] args) throws SQLException {
        DataSource dataSource;
        switch (poolType) {
            case "c3p0":
                dataSource = C3p0Builder.getDataSource(host, poolSize);
                break;
            case "dbcp":
                dataSource = DbcpBuilder.getDataSource(host, poolSize);
                break;
            case "druid":
                dataSource = DruidPoolBuilder.getDataSource(host, poolSize);
                break;
            case "hikari":
            default:
                dataSource = HikariCpBuilder.getDataSource(host, poolSize);
                poolType = "hikari";
        }

        log.info(">>>>>>>>>>>>>> connection pool Type: " + poolType);
        init(dataSource);

        try (Connection connection = dataSource.getConnection();
             Statement statement = connection.createStatement()) {
            String sql = "insert into " + dbName + ".t_1 values('2020-01-01 00:00:00.000',12.12,111)";
            int affectRows = statement.executeUpdate(sql);
            System.out.println("affectRows >>> " + affectRows);
            affectRows = statement.executeUpdate(sql);
            System.out.println("affectRows >>> " + affectRows);
        }

        /*ExecutorService executor = Executors.newFixedThreadPool(threadCount);
        for (long i = 0; i < totalSize / tableSize / batchSize; i++) {
            executor.execute(new InsertTask(dataSource, dbName, tableSize, batchSize));
            if (sleep > 0) {
                try {
                    // sleep few seconds
                    TimeUnit.MILLISECONDS.sleep(sleep);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        executor.shutdown();*/
    }

    private static void init(DataSource dataSource) throws SQLException {
        try (Connection conn = dataSource.getConnection()) {
            execute(conn, "drop database if exists " + dbName + "");
            execute(conn, "create database if not exists " + dbName + "");
            execute(conn, "use " + dbName + "");
            execute(conn, "create table weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)");
            for (int tb_ind = 1; tb_ind <= tableSize; tb_ind++) {
                execute(conn, "create table t_" + tb_ind + " using weather tags('beijing'," + (tb_ind + 1) + ")");
            }
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>> init finished.");
        }
    }

    private static void execute(Connection con, String sql) throws SQLException {
        try (Statement stmt = con.createStatement()) {
            stmt.executeUpdate(sql);
            log.info("SQL >>> " + sql);
        }
    }
}
